package com.swak.persistence.mybatis;

import java.util.List;

import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import com.swak.persistence.mybatis.filter.DefaultFilterChain;
import com.swak.persistence.mybatis.filter.Filter;

/**
 * 统一的拦截器： Executor 的 update 和两个 query 方法进行拦截
 * 
 * @author lifeng
 * @date 2021年2月2日 上午9:51:02
 */
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }),
		@Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
				RowBounds.class, ResultHandler.class }),
		@Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
				RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class }), })
public class UnifyInterceptor implements Interceptor {

	private List<Filter> filters;

	public UnifyInterceptor(List<Filter> filters) {
		this.filters = filters;
	}

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		return new DefaultFilterChain(filters).filter(invocation);
	}

	@Override
	public Object plugin(Object target) {
		if (target instanceof Executor) {
			return Plugin.wrap(target, this);
		}
		return target;
	}
}
